package com.tbm.console.proj.service.impl;

import com.tbm.console.proj.entity.SystemUser;
import com.tbm.console.proj.repository.SystemUserRepository;
import com.tbm.console.proj.service.SystemUserService;
import com.tbm.console.proj.view.SystemUserLocalUserInfoView;
import com.tbm.console.util.PageData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

@Slf4j
@Service
public class SystemUserServiceImpl implements SystemUserService {

    @Autowired
    private SystemUserRepository systemUserRepository;

    @Override
    public List<SystemUser> findAll() {
        return findAll(new PageData());
    }

    @Override
    public List<SystemUser> findAll(Integer start, Integer length) {
        return findAll(new PageData(),start,length);
    }

    @Override
    public List<SystemUser> findAll(PageData pageData) {
        return systemUserRepository.findAll(this.getSysteUserSpecification(pageData));
    }

    @Override
    public List<SystemUser> findAll(PageData pageData, Integer start, Integer length) {
        Sort sort = new Sort(Sort.Direction.ASC,"id");
        Pageable pageable = new PageRequest(start, length, sort);
        //使用 CriteriaBuilder方式来做过滤
        Specification<SystemUser> sp = this.getSysteUserSpecification(pageData);
        List<SystemUser> all = systemUserRepository.findAll(sp,pageable).getContent();
        return all;
    }

    @Override
    public SystemUser findById(Integer id) {
        Integer[] ids = new Integer[]{id};
        List<SystemUser> list = findAllById(ids);
        if(0==list.size()){
            return new SystemUser();
        }
        return list.get(0);
    }

    @Override
    public List<SystemUser> findAllById(Integer []ids) {
        return systemUserRepository.findAllById(Arrays.asList(ids));
    }

    @Override
    public long count() {
        return count(new PageData());
    }

    @Override
    public long count(SystemUser systemUser) {
        return systemUserRepository.count(Example.of(systemUser));
    }

    @Override
    public long count(PageData pageData) {
        //使用 CriteriaBuilder方式来做过滤
        return systemUserRepository.count(this.getSysteUserSpecification(pageData));
    }

    @Override
    public boolean deleteById(Integer id) {
        systemUserRepository.deleteById(id);
        return true;
    }

    @Override
    public boolean deleteByIds(Iterable<SystemUser> iterable) {
        systemUserRepository.deleteInBatch(iterable);
        return false;
    }


    @Override
    public SystemUser save(SystemUser systemUser) {
        List<SystemUser> list = saveAll(Arrays.asList(systemUser));
        return list.size() == 0 ? new SystemUser() : list.get(0);
    }

    @Override
    public List<SystemUser> saveAll(List<SystemUser> systemUsers) {
        return systemUserRepository.saveAll(systemUsers);
    }


    //通过Specification来获取自定义的查询条件
    private Specification<SystemUser> getSysteUserSpecification(PageData pageData) {
        return new Specification() {
            @Override
            public javax.persistence.criteria.Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> preList = new ArrayList<Predicate>();
                if (null != pageData.get("minCreateTime")) {
                    preList.add(criteriaBuilder.greaterThan(root.get("createTime"), pageData.get("minCreateTime").toString()));
                }
                if (null != pageData.get("maxCreateTime")) {
                    preList.add(criteriaBuilder.lessThan(root.get("createTime"), pageData.get("maxCreateTime").toString()));
                }
                if (null != pageData.get("roleId")) {
                    preList.add(criteriaBuilder.equal(root.get("roleId"), pageData.get("roleId").toString()));
                }
                if (null != pageData.get("username")) {
                    preList.add(criteriaBuilder.equal(root.get("username"), pageData.get("username").toString()));
                }
                if (null != pageData.get("belongTo")) {
                    preList.add(criteriaBuilder.equal(root.get("belongTo"), pageData.get("belongTo").toString()));
                }
                if (null != pageData.get("powerLevel")) {
                    preList.add(criteriaBuilder.equal(root.get("powerLevel"), pageData.get("powerLevel").toString()));
                }

                if (null != pageData.get("deleteFlag")) {
                    preList.add(criteriaBuilder.equal(root.get("deleteFlag"), pageData.get("deleteFlag").toString()));
                 }

                Predicate[] p = new Predicate[preList.size()];
                return criteriaBuilder.and(preList.toArray(p));
            }
        };
    }

    @Override
    public List<SystemUserLocalUserInfoView> findSystemUserLocalUserInfoView(PageData param, Integer start, Integer length) {

        List<Sort.Order> list = new ArrayList<>();
        Sort.Order menuNameOrder = new Sort.Order(Sort.Direction.DESC, "username");
        Sort.Order idOrder = new Sort.Order(Sort.Direction.ASC, "id");
        list.add(menuNameOrder);
        list.add(idOrder);
        Sort sort = new Sort(list);
        Pageable pageable = new PageRequest(start, length, sort);
        return systemUserRepository.findSystemUserLocalUserInfoView(pageable);
    }
}

